#!/bin/bash

###
### Program: timemachine
### File:    tm-archiver.sh
### Version: 2.0
### Owner:   raptus ag
### Author:  Florian S.
### Purpose:
###
### Archives backup done by tm-onsite
### into daily, weekly, monthly and 
### yearly backups
###

#
# standard stuff
#

if ! test "$#" -le 2
then
    echo "Usage: $0 <config-file> [extra]"
    exit 1
fi

ME=`basename $0 | head -c -4`

SCRIPT=$(readlink -f $0)
SCRIPTPATH=`dirname $SCRIPT`
OLDDIR="`pwd`"
cd $SCRIPTPATH

if test "$1" == "--help"
then
    echo "Usage: $0 <config-file> [extra]"
    exit 1
fi

CONFIGFILE="$1"
if ! test -f "$CONFIGFILE"
then
    echo "ERROR: Cannot find config file $CONFIGFILE"
    exit 1
fi

if ! test -z "$2"
then
    EXTRA="true"
fi

source "../config/defaults.conf"
source "$CONFIGFILE"
source "functions/locking.inc.sh"
source "functions/logging.inc.sh"
source "functions/errorcodes.inc.sh"

echo "Archiver Debuglog `date`" > $DEBUGARCHIVE 2>&1

log "-----------------------------------------------------------------------"
log "This is $CUSTOMER $HOSTNAME timemachine archiver"
log "Config $CONFIGFILE, Job $JOBNAME"
lock
if [ $? == 1 ];
then
        log "ERROR: Lockfile present, exiting."
        log "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
        send "error"
        exit 1
fi


#
# checking internal file structure
#

TARGETBASE="$BACKUPDIR/$CUSTOMER/archive"

if ! test -d "$BACKUPDIR/$CUSTOMER/upload"
then
    log "ERROR: No current backup available. exiting. Searched at $BACKUPDIR/$CUSTOMER/upload"
    log "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
    unlock
    send "error"
	exit 1
fi

if test -z "$EXTRA"
then

    if ! test -d "$TARGETBASE"
    then
        mkdir -p "$TARGETBASE" >> $DEBUGARCHIVE 2>&1
    fi

    if ! test -d "$TARGETBASE/daily"
    then
	    mkdir -p "$TARGETBASE/daily" >> $DEBUGARCHIVE 2>&1
    fi

    if ! test -d "$TARGETBASE/monthly"
    then
        mkdir -p "$TARGETBASE/monthly" >> $DEBUGARCHIVE 2>&1
    fi

    if ! test -d "$TARGETBASE/weekly"
    then
        mkdir -p "$TARGETBASE/weekly" >> $DEBUGARCHIVE 2>&1
    fi

    if ! test -d "$TARGETBASE/yearly"
    then
        mkdir -p "$TARGETBASE/yearly" >> $DEBUGARCHIVE 2>&1
    fi

else
    EXTRADIR="$BACKUPDIR/$CUSTOMER/extra"

    if ! test -d "$EXTRADIR"
    then
        mkdir -p "$EXTRADIR" >> $DEBUGARCHIVE 2>&1
    fi
fi


#
# determine the backup type (daily, weekly, monthly, yearly)
#

TODAY="`date +%s`"
FOLDERNAME="`date +%Y%m%d`"

if test -z "$EXTRA"
then

    ENDOFWEEK="`date --date=\"next Friday - 7 days\" +%Y%m%d`"
    ENDOFMONTH="`date --date=\"-$(date +%d) days +1 month\" +%Y%m%d`"
    ENDOFYEAR="`date +%Y`1231"

    TODAY="`date +%Y%m%d`"

    BACKUPTYPE=""

    if [ "$RETENTION_DAILY" -ne "0" ] ; then BACKUPTYPE="daily" ; MAXAGE="$RETENTION_DAILY"   ; fi
    if [ "$TODAY" -eq "$ENDOFWEEK" ] && [ "$RETENTION_WEEKLY"  -ne "0" ] ; then BACKUPTYPE="weekly" ; MAXAGE="$RETENTION_WEEKLY" ; fi
    if [ "$TODAY" -eq "$ENDOFMONTH" ] && [ "$RETENTION_MONTHLY" -ne "0" ] ; then BACKUPTYPE="monthly" ; MAXAGE="$RETENTION_MONTHLY" ; fi
    if [ "$TODAY" -eq "$ENDOFYEAR" ] && [ "$RETENTION_YEARLY"  -ne "0" ] ; then BACKUPTYPE="yearly" ; MAXAGE="$RETENTION_YEARLY" ; fi


    #
    # check if an extraordinary backup is needed
    #

    LASTYEARLY="`ls \"/$TARGETBASE/yearly\" -ltr --time-style=\"+%s\" | tail -1 | awk '{ print $6 }'`"
    LASTMONTHLY="`ls \"/$TARGETBASE/monthly\" -ltr --time-style=\"+%s\" | tail -1 | awk '{ print $6 }'`"
    LASTWEEKLY="`ls \"/$TARGETBASE/weekly\" -ltr --time-style=\"+%s\" | tail -1 | awk '{ print $6 }'`"


    if test -z "$LASTYEARLY" ;  then LASTYEARLY="0" ; fi
    if test -z "$LASTMONTHLY" ; then LASTMONTHLY="0" ; fi
    if test -z "$LASTWEEKLY" ;  then LASTWEEKLY="0" ; fi

    DIFFYEARLY=$(($TODAY-$LASTYEARLY))
    DIFFMONTHLY=$(($TODAY-$LASTMONTHLY))
    DIFFWEEKLY=$(($TODAY-$LASTWEEKLY))

    DIFFYEARLY=$(($DIFFYEARLY/(60*60*24)))
    DIFFMONTHLY=$(($DIFFMONTHLY/(60*60*24)))
    DIFFWEEKLY=$(($DIFFWEEKLY/(60*60*24)))

    SUFFIX=""

    UPPEROLD="`echo $BACKUPTYPE | tr \"[:lower:]\" \"[:upper:]\"`"

    CONTROLWEEKLY="7"
    CONTROLMONTHLY="31"
    CONTROLYEARLY="365"

    if [ "$DIFFWEEKLY" -gt "$CONTROLWEEKLY" ]   && [ "$RETENTION_WEEKLY" -ne "0" ];  then BACKUPTYPE="weekly"  ; MAXAGE="$RETENTION_WEEKLY"  ; SUFFIX="-extra" ; fi
    if [ "$DIFFMONTHLY" -gt "$CONTROLMONTHLY" ] && [ "$RETENTION_MONTHLY" -ne "0" ]; then BACKUPTYPE="monthly" ; MAXAGE="$RETENTION_MONTHLY" ; SUFFIX="-extra" ; fi
    if [ "$DIFFYEARLY" -gt "$CONTROLYEARLY" ]   && [ "$RETENTION_YEARLY" -ne "0" ];  then BACKUPTYPE="yearly"  ; MAXAGE="$RETENTION_YEARLY"  ; SUFFIX="-extra" ; fi

    UPPERNEW="`echo $BACKUPTYPE | tr \"[:lower:]\" \"[:upper:]\"`"

    FOLDERNAME="$FOLDERNAME""$SUFFIX"

    mkdir -p $TARGETBASE/$BACKUPTYPE/$FOLDERNAME/$HOSTNAME/$JOBNAME >> $DEBUGARCHIVE 2>&1

    if [ "$SUFFIX" == "-extra" ]
    then
        log "ATTENTION: Skipping $UPPEROLD backup due to missing $UPPERNEW backup."
    fi

else
    BACKUPTYPE="extra"
    UPPERNEW="EXTRA"

    log "ATTENTION: This is a manual extraordinary backup."

    mkdir -p "$EXTRADIR/$FOLDERNAME/$HOSTNAME/$JOBNAME" >> $DEBUGARCHIVE 2>&1
fi


#
# archiving job
#

if test -z "$BACKUPTYPE" 
then
    log "ATTENTION: No backup sheduled for today."

else

    log "Archiving $UPPERNEW backup to folder $FOLDERNAME"

    MAILMESSAGE="success"

    
    if test "$BIGARCHIVE" == "on"
    then
        SRCPATH="$BACKUPDIR/$CUSTOMER/upload"
        DSTPATH="$TARGETBASE/$BACKUPTYPE/$FOLDERNAME"
        LNKPATH="$BACKUPDIR/$CUSTOMER/upload"
    else
        SRCPATH="$BACKUPDIR/$CUSTOMER/upload/$HOSTNAME/$JOBNAME"
        DSTPATH="$TARGETBASE/$BACKUPTYPE/$FOLDERNAME/$HOSTNAME/$JOBNAME"
        LNKPATH="$BACKUPDIR/$CUSTOMER/upload/$HOSTNAME/$JOBNAME"
    fi

    if ! test -d "$SRCPATH"
    then
        log "ERROR: Archive source not found! [$SRCPATH]. exiting."
        log "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
        unlock
        send "error"
        exit 1
    fi


    ls $SRCPATH | while read -r DIR
    do

        SRC="$SRCPATH/$DIR"
        DST="$DSTPATH"

        if ! test -z "$EXTRA"
        then
            DST="$EXTRADIR/$FOLDERNAME/$HOSTNAME/$JOBNAME"
        fi

        LNK="$LNKPATH"

        if test -z "$RSYNCARCHIVER"; then RSYNCARCHIVER="--archive --hard-links --stats --human-readable --verbose"; fi

        if test -z "$NICELEVEL"; then NICELEVEL="18"; fi

        STATS=`nice -n $NICELEVEL rsync $RSYNCARCHIVER --link-dest="$LNK" "$SRC" "$DST" | tee $DEBUGARCHIVE 2>&1`
        RET=$?

        F=`echo "$STATS" | tail -n 14 | grep "Total file size" | cut -d " " -f 4`
        T=`echo "$STATS" | tail -n 14 | grep "Total transferred file size" | cut -d " " -f 5`

        # getting rsync error code
        rsync_status $RET

        if [[ "$RSYNCMSG" == *ERROR* ]]; then MAILMESSAGE="failed"; fi
    done
fi


# 
# cleanup
#

BACKUPTYPES="daily weekly monthly yearly"

if test -z "$EXTRA"
then
    for i in $BACKUPTYPES
    do

        if [ "$i" == "daily" ] ;   then COMPARE=$RETENTION_DAILY ;   fi
        if [ "$i" == "weekly" ] ;  then COMPARE=$RETENTION_WEEKLY ;  fi
        if [ "$i" == "monthly" ] ; then COMPARE=$RETENTION_MONTHLY ; fi
        if [ "$i" == "yearly" ] ;  then COMPARE=$RETENTION_YEARLY ;  fi

        COUNT=0

        for j in `ls $TARGETBASE/$i/ -t`
        do
            let COUNT=$COUNT+1

            if test $COUNT -gt $COMPARE 
            then
                log "Deleting old Backup $j..."
                rm -Rf "$TARGETBASE/$i/$j" >> $DEBUGARCHIVE 2>&1
            fi
   
        done
    done

else
    log "No cleanup work due to manual extraordinary backup."

fi

unlock

log "Archiving done."
log "-----------------------------------------------------------------------"

if [ "$ARCHIVEMAIL" == "off" ]; then ARCHIVEMAIL=""; fi

if ! test -z "$ARCHIVEMAIL"; then send "$MAILMESSAGE"; fi

# eof
